; shellfunctions.asm

GLOBAL cpustring
GLOBAL cputype
GLOBAL readclock
GLOBAL writeclock
GLOBAL clear
GLOBAL setcursor
GLOBAL outpw
GLOBAL inpw
GLOBAL capson
GLOBAL capsoff
GLOBAL setdelay, typematic

SECTION .text

outpw:		push EBP		; guarda el stackframe
        	mov EBP, ESP
		mov EDX, [EBP+8]
		mov EAX, [EBP+12]
		out DX, Al
		pop	EBP
		ret	

inpw:		push EBP		; guarda el stackframe
        	mov EBP, ESP
		mov EDX, [EBP+8]
		mov ECX, [EBP+12]
		in AL, DX
		mov [ECX], AL
		pop	EBP
		ret


setcursor:	push EBP		; guarda el stackframe
        	mov EBP, ESP
		;cli
		mov ebx, [ebp+8]
		mov ecx, [ebp+12]
		mov eax, 80
		mul ebx
		add eax, ecx

		mov ecx, eax
		
		mov al, 0eh
		mov dx, 03D4h
		out dx, al
		mov al, ch
		mov dx, 03D5h
		out dx, al

		mov al, 0fh
		mov dx, 03D4h
		out dx, al
		mov al, cl
		mov dx, 03D5h
		out dx, al

		;sti
		pop EBP
		ret

setdelay:	push EBP		; guarda el stackframe
        	mov EBP, ESP
		push ebx
		push ecx
		;cli
		mov ebx, [ebp+8]
		mov ecx, [ebp+12]
		

		mov al, 0f3h
		out 60h, al
		in ax, 60h
		mov al, 00h		;
		out 60h, al
		in ax, 60h		

		;sti
		pop ecx
		pop ebx
		pop EBP
		ret

typematic:	push EBP		; guarda el stackframe
        	mov EBP, ESP
		
		;cli
		;mov al, 0f0h
		;out 60h, al
		;in ax, 60h
		;mov al, 03h
		;out 60h, al
		;in ax, 60h


;http://docs.huihoo.com/help-pc/hw-keyboard_commands.html
		mov al, 0f6h ; set default 
		out 60h, al
		in ax, 60h

		;sti
		pop EBP
		ret

capson: 	push EBP		; guarda el stackframe
        	mov EBP, ESP
		
		mov al, 0edh
		out 60h, al
		in ax, 60h
		mov al, 04h
		out 60h, al
		in ax, 60h

		pop EBP
		ret

capsoff: 	push EBP		; guarda el stackframe
        	mov EBP, ESP
		
		
		mov al, 0edh
		out 60h, al
		in ax, 60h
		mov al, 00h
		out 60h, al
		in ax, 60h

		pop EBP
		ret


cpustring:	push EBP
		mov EBP, ESP
		mov EAX, 00h
		cpuid
		mov EAX, [EBP+8]
		mov [EAX], EBX
		mov [EAX+4], EDX
		mov [EAX+8], ECX

		pop EBP
		ret

cputype:	push EBP
		mov EBP, ESP
		
		mov EAX, 01h
		cpuid

		pop EBP
		ret



SECTION .data

data1	equ	00h
data2	equ	0FFh




SECTION .text


; readclock: lee un registro del RTC que recibe como parametro

readclock:	push EBP		; guarda el stackframe
        	mov EBP, ESP

		mov EBX, [EBP+8]	; levanta registro a leer
 		mov ECX, [EBP+12]	; levanta direccion de respuesta

		mov EAX, EBX		; copia registro a leer

		out 70h, AL		; indica registro a leer
		mov EAX, 0		; limpia el registro EAX
		in AL, 71h		; lee registro
		
		push EAX
		call bcdtoi		; transforma BCD en entero
		pop EAX

		mov [ECX], EAX		; escribe el resultado

		pop EBP			; restaura el stackframe
		ret


; bcdtoi: transforma un byte expresado en BCD en un entero en binario

bcdtoi:      	push EBP		; guarda el stackframe
        	mov EBP, ESP
		mov EDX, [EBP+8]	; levanta el numero a transformar
		push EAX
		push EBX
		push ECX

		mov EAX, EDX
		mov EBX, 0		; limpia registro EBX
	
		mov BL, AL      	; comienza la conversion		
		and BL, 0F0h
		shr BL, 4

		mov ECX, 0Ah
		mov DL, BL
		mov BL, 0

adding:		add BL, DL		; multiplica por diez
		dec ECX
		jnz adding

		and AL, 0Fh
		add AL, BL		; finaliza la conversion

		mov EDX, EAX
		pop ECX
		pop EBX
		pop EAX
		mov [EBP+8], EDX	; devuelve el resultado
		pop EBP
		ret


; writeclock: escribe un registro del RTC que recibe como parametro

writeclock:	push EBP		; guarda el stackframe
        	mov EBP, ESP

		mov EBX, [EBP+8]	; levanta registro a escribir
 		mov ECX, [EBP+12]	; levanta valor a escribir

		mov EAX, EBX		; copia registro a escribir
	
		push ECX
		call itobcd		; convierte BCD a entero
		pop ECX

		out 70h, AL		; indica registro a escribir
		mov AL, CL
		out 71h, AL		; escribe registro

		pop EBP			; restaura stackframe
		ret


; itobcd: transforma un byte expresado como entero en BCD

itobcd:      	push EBP		; guarda el stackframe
        	mov EBP, ESP
		mov EDX, [EBP+8]	; levanta el numero a transformar
		push EAX
		push EBX
		push ECX

		mov EAX, EDX
		mov EBX, 0		; limpia registro EBX
	
		mov ECX, 0Ah		; comienza la conversion
		div CL			; divide por diez
		mov BL, AL		; cociente en AL
		shl BL, 4
		add BL, AH		; resto en AH
		mov EAX, EBX		; fin de conversion

		mov EDX, EAX
		pop ECX
		pop EBX
		pop EAX
		mov [EBP+8], EDX	; devuelve el resultado
		pop EBP
		ret

